package com.hyt.it.ogt.ykcj.service.grade.impl;

import com.hyt.it.ogt.ykcj.common.annotation.ChangedExam;
import com.hyt.it.ogt.ykcj.common.constant.Constants;
import com.hyt.it.ogt.ykcj.common.core.domain.entity.SysUser;
import com.hyt.it.ogt.ykcj.common.enums.BizErrorCode;
import com.hyt.it.ogt.ykcj.common.exception.CustomException;
import com.hyt.it.ogt.ykcj.common.utils.DateUtils;
import com.hyt.it.ogt.ykcj.common.utils.IdUtils;
import com.hyt.it.ogt.ykcj.common.utils.SecurityUtils;
import com.hyt.it.ogt.ykcj.domain.exam.ExamSubjectInfo;
import com.hyt.it.ogt.ykcj.domain.grade.ExamineeGradeInfo;
import com.hyt.it.ogt.ykcj.domain.grade.ExamineeSubjectGradeInfo;
import com.hyt.it.ogt.ykcj.domain.vo.ExamineeSubjectGradeInfoVo;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamSubjectInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ExamineeGradeInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ExamineeSubjectGradeInfoMapper;
import com.hyt.it.ogt.ykcj.service.exam.IChangedExamInfoService;
import com.hyt.it.ogt.ykcj.service.grade.IExamineeSubjectGradeInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 考生考试科目成绩信息Service业务层处理
 * 
 * @author admin
 * @date 2021-06-17
 */
@Service
public class ExamineeSubjectGradeInfoServiceImpl implements IExamineeSubjectGradeInfoService
{
    private static final Logger log = LoggerFactory.getLogger(ExamineeSubjectGradeInfoServiceImpl.class);

    @Autowired
    private ExamineeSubjectGradeInfoMapper examineeSubjectGradeInfoMapper;

    @Autowired
    private ExamSubjectInfoMapper subjectInfoMapper;

    @Autowired
    private ExamineeGradeInfoMapper examineeGradeInfoMapper;

    @Autowired
    IChangedExamInfoService changedExamInfoService;


    /**
     * 查询考生考试科目成绩信息
     *
     * @param subjectGradeId 考生考试科目成绩信息ID
     * @return 考生考试科目成绩信息
     */
    @Override
    public ExamineeSubjectGradeInfo selectExamineeSubjectGradeInfoById(String subjectGradeId)
    {
        return examineeSubjectGradeInfoMapper.selectExamineeSubjectGradeInfoById(subjectGradeId);
    }

    /**
     * 查询考生考试科目成绩信息列表
     *
     * @param examineeSubjectGradeInfo 考生考试科目成绩信息
     * @return 考生考试科目成绩信息
     */
    @Override
    public List<ExamineeSubjectGradeInfo> selectExamineeSubjectGradeInfoList(ExamineeSubjectGradeInfo examineeSubjectGradeInfo)
    {
        return examineeSubjectGradeInfoMapper.selectExamineeSubjectGradeInfoList(examineeSubjectGradeInfo);
    }

    /**
     * 新增考生考试科目成绩信息
     *
     * @param examineeSubjectGradeInfo 考生考试科目成绩信息
     * @return 结果
     */
    @Override
    public int insertExamineeSubjectGradeInfo(ExamineeSubjectGradeInfo examineeSubjectGradeInfo)
    {
        examineeSubjectGradeInfo.setCreateTime(DateUtils.getNowDate());
        return examineeSubjectGradeInfoMapper.insertExamineeSubjectGradeInfo(examineeSubjectGradeInfo);
    }

    /**
     * 修改考生考试科目成绩信息
     *
     * @param subjectGradeInfo 考生考试科目成绩信息
     * @return 结果
     */
    @Override
    @Transactional
    @ChangedExam
    public void updateExamineeSubjectGradeInfo(ExamineeSubjectGradeInfoVo subjectGradeInfo)
    {
        // 校验科目成绩信息是否被删除
        ExamineeSubjectGradeInfo examineeSubjectGradeInfo = examineeSubjectGradeInfoMapper.selectExamineeSubjectGradeInfoById(subjectGradeInfo.getSubjectGradeId());
        if (null == examineeSubjectGradeInfo) {
            throw new CustomException(BizErrorCode.GRADE_E0003);
        }

        // 已归档的成绩在成绩导入页面不可修改
        if (Constants.ARCHIVE_TYPE_0.equals(subjectGradeInfo.getEditType()) && Constants.ARCHIVED_STATUS_Y.equals(examineeSubjectGradeInfo.getArchivedStatus())) {
            throw new CustomException(BizErrorCode.GRADE_E0004);
        }

        subjectGradeInfo.setUpdateTime(DateUtils.getNowDate());
        subjectGradeInfo.setUpdateBy(SecurityUtils.getUsername());
        //  根据考试ID和科目ID查出对应科目的合格成绩以及有效期。成绩有效期需要归档才计算

        // 科目成绩对应的合格成绩配置信息
        ExamSubjectInfo examSubjectInfo = subjectInfoMapper.selectExamSubjectInfoById(subjectGradeInfo.getSubjectId());
        //  校验考试对应的合格成绩配置
        if (null == examSubjectInfo){
            throw new CustomException(BizErrorCode.EXAM_E0011);
        }
        if (null != examSubjectInfo.getPaperFullMarks()) {
            if (subjectGradeInfo.getExamineeScore().compareTo(examSubjectInfo.getPaperFullMarks()) == 1) {
                throw new CustomException("考生科目成绩不能大于试卷满分");
            }
        }
        if (null != examSubjectInfo.getEligibilityCriteria() && null != subjectGradeInfo.getExamineeScore()){
            if (subjectGradeInfo.getExamineeScore().compareTo(examSubjectInfo.getEligibilityCriteria()) > -1){
                subjectGradeInfo.setPassFlag(Constants.PASS_FLAT_Y);
            }else {
                subjectGradeInfo.setPassFlag(Constants.PASS_FLAT_N);
            }

        }
        examineeSubjectGradeInfoMapper.updateExamineeSubjectGradeInfo(subjectGradeInfo);

        // 更改科目成绩为不合格则总成绩不合格。更改科目成绩为合格则校验所有成绩是否合格
        String passFlag = null;
        // 考生考试科目成绩列表
        ExamineeGradeInfo examineeGradeInfo = examineeGradeInfoMapper.selectExamineeGradeInfoById(examineeSubjectGradeInfo.getGradeId());
        if (null == examineeGradeInfo){
            throw new CustomException(BizErrorCode.GRADE_E0001);
        }
        if (Constants.PASS_FLAT_N.equals(subjectGradeInfo.getPassFlag())){
            passFlag = Constants.PASS_FLAT_N;
        }else {
            passFlag = checkGradeInfoPassFlag(examineeSubjectGradeInfo.getGradeId(),examineeGradeInfo.getExamId());
        }

        // 前后不一致则修改合格状态
        if (!examineeGradeInfo.getPassFlag().equals(passFlag)){
            updatePassFlag(examineeGradeInfo,passFlag);
        }
        // 设置需要变更的考试id信息
        Constants.changedExamId.set(examineeGradeInfo.getExamId());

    }

    /**
     * 批量删除考生考试科目成绩信息
     *
     * @param subjectGradeIds 需要删除的考生考试科目成绩信息ID
     * @return 结果
     */
    @Override
    public int deleteExamineeSubjectGradeInfoByIds(String[] subjectGradeIds)
    {
        return examineeSubjectGradeInfoMapper.deleteExamineeSubjectGradeInfoByIds(subjectGradeIds);
    }

    /**
     * 删除考生考试科目成绩信息信息
     *
     * @param subjectGradeId 考生考试科目成绩信息ID
     * @return 结果
     */
    @Override
    @ChangedExam
    public int deleteExamineeSubjectGradeInfoById(String subjectGradeId)
    {
        ExamineeSubjectGradeInfo subjectGradeInfo = examineeSubjectGradeInfoMapper.selectExamineeSubjectGradeInfoById(subjectGradeId);
        if (null == subjectGradeInfo){
            throw new CustomException(BizErrorCode.GRADE_E0003);
        }
        ExamineeGradeInfo examineeGradeInfo = examineeGradeInfoMapper.selectExamineeGradeInfoById(subjectGradeInfo.getGradeId());
        // 删除科目被当做缺考，成绩设置为不合格
        examineeGradeInfo.setPassFlag(Constants.PASS_FLAT_N);
        examineeGradeInfoMapper.updateExamineeGradeInfo(examineeGradeInfo);
        // 插入需要变更的考试信息
        Constants.changedExamId.set(examineeGradeInfo.getExamId());
        return examineeSubjectGradeInfoMapper.deleteExamineeSubjectGradeInfoById(subjectGradeId);
    }

    /**
     * 新增、修改和删除科目成绩需要校验是否需要更改学生考试成绩合格状态
     */
    public String checkGradeInfoPassFlag(String gradeId,String examId){
        String passFlag = Constants.PASS_FLAT_Y;
        // 查询考生科目成绩列表
        List<ExamineeSubjectGradeInfo> subjectGradeInfoList = examineeSubjectGradeInfoMapper.selectSubjectGradeInfoListByGradeId(gradeId);
        // 查出当前考试有多少个科目,如果考试科目成绩数少于科目数则设置为不合格
        List<ExamSubjectInfo> subjectInfoList = subjectInfoMapper.selectExamSubjectInfoListById(examId);
        if (!CollectionUtils.isEmpty(subjectGradeInfoList)){
            // 科目数量不一致则判断为不合格
            if (subjectInfoList.size() != subjectGradeInfoList.size()){
                passFlag = Constants.PASS_FLAT_N;
                return passFlag;
            }
            // 判断每科成绩的通过状态来决定总成绩是否通过
            for (ExamineeSubjectGradeInfo tmp:subjectGradeInfoList) {
                if (Constants.PASS_FLAT_N.equals(tmp.getPassFlag())){
                    passFlag = Constants.PASS_FLAT_N;
                    break;
                }
            }
        }
        return passFlag;
    }

    @Override
    @ChangedExam
    public void addExamineeSubjectGradeInfo(ExamineeSubjectGradeInfo examineeSubjectGradeInfo,SysUser user) {

        ExamineeGradeInfo gradeInfo = examineeGradeInfoMapper.selectExamineeGradeInfoById(examineeSubjectGradeInfo.getGradeId());
        if (null == gradeInfo){
            throw new CustomException(BizErrorCode.GRADE_E0001);
        }

        // 判断考生科目成绩信息是否存在信息
        ExamineeSubjectGradeInfo queryInfo = new ExamineeSubjectGradeInfo();
        queryInfo.setGradeId(examineeSubjectGradeInfo.getGradeId());
        queryInfo.setSubjectId(examineeSubjectGradeInfo.getSubjectId());
        List<ExamineeSubjectGradeInfo> examineeSubjectGradeInfoList = examineeSubjectGradeInfoMapper.selectExamineeSubjectGradeInfoList(queryInfo);
        if (!CollectionUtils.isEmpty(examineeSubjectGradeInfoList)){
            throw new CustomException(BizErrorCode.GRADE_E0007);
        }

        List<ExamSubjectInfo> examSubjectInfoList = subjectInfoMapper.selectExamSubjectInfoListById(gradeInfo.getExamId());
        Map<String,ExamSubjectInfo> subjectInfoMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(examSubjectInfoList)){
            subjectInfoMap = examSubjectInfoList.stream().collect(Collectors.toMap(ExamSubjectInfo::getId,subjectInfo->subjectInfo));
        }
        examineeSubjectGradeInfo.setExamId(gradeInfo.getExamId());
        this.initSubjectGradeInfo(examineeSubjectGradeInfo,subjectInfoMap,gradeInfo.getGradeId(),user);
        examineeSubjectGradeInfoMapper.insertExamineeSubjectGradeInfo(examineeSubjectGradeInfo);
        // 更新考生全科通过状态
        String passFlag = checkGradeInfoPassFlag(gradeInfo.getGradeId(),gradeInfo.getExamId());
        if (!passFlag.equals(gradeInfo.getPassFlag())){
            updatePassFlag(gradeInfo,passFlag);
        }
        if (Constants.ARCHIVED_STATUS_Y.equals(gradeInfo.getArchivedStatus())) {
            gradeInfo.setArchivedStatus(Constants.ARCHIVED_STATUS_N);
            examineeGradeInfoMapper.updateExamineeGradeInfo(gradeInfo);
        }
        // 插入需要变更的考试信息
        Constants.changedExamId.set(gradeInfo.getExamId());
    }

    /**
     * 更新考生成绩合格状态
     * @param gradeInfo
     * @param passFlag
     */
    private void updatePassFlag(ExamineeGradeInfo gradeInfo,String passFlag){
        gradeInfo.setPassFlag(passFlag);
        if (Constants.PASS_FLAT_Y.equals(passFlag)){
            gradeInfo.setPassDate(DateUtils.getDate());
        }else {
            gradeInfo.setPassDate(null);
        }
        gradeInfo.setUpdateTime(DateUtils.getNowDate());
        gradeInfo.setUpdateBy(SecurityUtils.getUsername());
        examineeGradeInfoMapper.updateExamineeGradeInfo(gradeInfo);
    }

    /**
     * 初始化科目信息
     * @param examineeSubjectGradeInfo
     * @param subjectInfoMap
     * @param gradeId
     * @param user
     */
    @Override
    public void initSubjectGradeInfo(ExamineeSubjectGradeInfo examineeSubjectGradeInfo, Map<String, ExamSubjectInfo> subjectInfoMap, String gradeId, SysUser user) {
        examineeSubjectGradeInfo.setGradeId(gradeId);
        examineeSubjectGradeInfo.setSubjectGradeId(IdUtils.generateId());
        examineeSubjectGradeInfo.setCreateBy(user.getUserName());
        examineeSubjectGradeInfo.setCreateTime(DateUtils.getNowDate());
        examineeSubjectGradeInfo.setUpdateBy(user.getUserName());
        examineeSubjectGradeInfo.setUpdateTime(DateUtils.getNowDate());
        examineeSubjectGradeInfo.setPassFlag(Constants.PASS_FLAT_N);
        // 新增的科目成绩默认不归档
        examineeSubjectGradeInfo.setArchivedStatus(Constants.ARCHIVED_STATUS_N);
        // 判断成绩是否合格，先查出考试对应的科目的所有合格成绩
        ExamSubjectInfo info = subjectInfoMap.get(examineeSubjectGradeInfo.getSubjectId());
        if (null == info){
            throw new CustomException(BizErrorCode.EXAM_E0011);
        }
        if (null != info.getPaperFullMarks()) {
            if (examineeSubjectGradeInfo.getExamineeScore().compareTo(info.getPaperFullMarks()) == 1) {
                throw new CustomException("考生科目成绩不能大于试卷满分");
            }
        }
        if (null != info.getEligibilityCriteria() && null != examineeSubjectGradeInfo.getExamineeScore()) {
            if (examineeSubjectGradeInfo.getExamineeScore().compareTo(info.getEligibilityCriteria()) > -1){
                examineeSubjectGradeInfo.setPassFlag(Constants.PASS_FLAT_Y);
            }
        }
    }

    @Override
    public void batchInvalidGradeInfo() {
        // TODO 查询出所有已归档的考试科目成绩信息，分页
        //examineeSubjectGradeInfoMapper.
    }
}

